/*
 * Date：10/23/18 10:15 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.biz.service.core.resident.impl;

import org.apache.commons.lang3.StringUtils;
import org.elanfox.intellicommunity.biz.dto.condition.WorkerCondition;
import org.elanfox.intellicommunity.biz.dto.msg.LocationMsgDTO;
import org.elanfox.intellicommunity.biz.dto.resident.WorkerSaveDTO;
import org.elanfox.intellicommunity.biz.entity.equipment.CardPO_;
import org.elanfox.intellicommunity.biz.entity.resident.*;
import org.elanfox.intellicommunity.biz.repository.resident.WorkerRepository;
import org.elanfox.intellicommunity.biz.service.core.msg.LocationMsgService;
import org.elanfox.intellicommunity.biz.service.core.resident.UserService;
import org.elanfox.intellicommunity.biz.service.core.resident.WorkerService;
import org.elanfox.intellicommunity.common.ienum.UserEnums;
import org.elanfox.intellicommunity.data.base.base.AbstractSearchableCrudService;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 用户相关service
 *
 * @author loutianxi
 * @date 2019-12-05
 */
@Service
public class WorkerServiceImpl extends AbstractSearchableCrudService<WorkerPO, Integer> implements WorkerService {

    private WorkerRepository repository;
    @Autowired
    private UserService userService;
    @Autowired
    private LocationMsgService locationMsgService;

    @Autowired
    protected WorkerServiceImpl(WorkerRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Override
    protected SpecificationAndSort<WorkerPO> specificationAndSort(BaseSearchDTO condition) {
        WorkerCondition workerCondition = (WorkerCondition) condition;
        Specification<WorkerPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotEmpty(workerCondition.getCardNo())) {
                predicates.add(cb.equal(root.get(WorkerPO_.user).get(UserPO_.card).get(CardPO_.cardNo), workerCondition.getCardNo()));
            }
            if (StringUtils.isNotEmpty(workerCondition.getName())) {
                predicates.add(cb.like(root.get(WorkerPO_.user).get(UserPO_.name), likeAll(workerCondition.getName())));
            }
            if (StringUtils.isNotEmpty(workerCondition.getWorkNo())) {
                predicates.add(cb.like(root.get(WorkerPO_.workNo), likeAll(workerCondition.getWorkNo())));
            }
            if (workerCondition.getOrgId() != null) {
                predicates.add(cb.equal(root.get(WorkerPO_.organization).get(OrganizationPO_.orgId), workerCondition.getOrgId()));
            }
            if (workerCondition.getDelFlag() != null) {
                predicates.add(cb.equal(root.get(WorkerPO_.user).get(UserPO_.DEL_FLAG), workerCondition.getDelFlag()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public WorkerPO save(BaseSaveDTO saveDTO) {
        WorkerSaveDTO workerSaveDTO = (WorkerSaveDTO) saveDTO;
        WorkerPO workerPO = findById(workerSaveDTO.getUserId());
        if (workerPO == null) {
            workerPO = new WorkerPO();
            workerSaveDTO.setType(UserEnums.Type.WORKER);
        }
        UserPO userPO = userService.save(workerSaveDTO);
        workerPO.setUser(userPO);
        OrganizationPO org = new OrganizationPO();
        org.setOrgId(workerSaveDTO.getOrgId());
        workerPO.setOrganization(org);
        workerPO.setWorkNo(workerSaveDTO.getWorkNo());
        workerPO.setSteward(workerSaveDTO.isSteward());
        return repository.save(workerPO);
    }

    @Override
    public long countByOrgId(Integer orgId) {
        return repository.countByOrganization_OrgId(orgId);
    }

    @Override
    public List<WorkerPO> findAllSteward() {
        return repository.findByStewardIsTrue();
    }

    @Override
    public List<WorkerPO> findStewardsInLocator() {
        List<WorkerPO> pos = repository.findByStewardIsTrue();

        Iterator<WorkerPO> iterator = pos.iterator();
        while (iterator.hasNext()) {
            WorkerPO po = iterator.next();
            LocationMsgDTO dto = locationMsgService.findLastByUser(po.getUser().getUserId());
            if (dto == null) {
                iterator.remove();
            }
        }

        return pos;
    }

    @Override
    public List<WorkerPO> findWorkerByStructureId(Integer strId) {
        return repository.findWorkByStrId(strId);
    }
}
